/**
 * @fileoverview style 插件
 */
function style() {
  this.styles = []
}

// #ifndef APP-PLUS-NVUE
const parser = require('./parser')

style.prototype.onParse = function (node, vm) {
  // 获取样式
  if (node.name == 'style' && node.children.length && node.children[0].type == 'text') {
    this.styles = this.styles.concat(new parser().parse(node.children[0].text))
  }
  // 匹配样式（对非文本标签）
  else if (node.name) {
    // 存储不同优先级的样式 name < class < id < 后代
    var matched = ['', '', '', '']
    for (var i = 0, len = this.styles.length; i < len; i++) {
      var item = this.styles[i], j,
        res = match(node, item.key || item.list[item.list.length - 1])
      if (res) {
        // 后代选择器
        if (!item.key) {
          j = item.list.length - 2
          for (var k = vm.stack.length; j >= 0 && k--;) {
            // 子选择器
            if (item.list[j] == '>') {
              // 错误情况
              if (j < 1 || j > item.list.length - 2)
                break
              if (match(vm.stack[k], item.list[j - 1]))
                j -= 2
              else
                j++
            }
            else if (match(vm.stack[k], item.list[j]))
              j--
          }
          res = 4
        }
        if (item.key || j < 0) {
          // 添加伪类
          if (item.pseudo && node.children) {
            var text
            item.style = item.style.replace(/content:([^;]+)/, (_, $1) => {
              text = $1.replace(/['"]/g, '')
                // 处理 attr 函数
                .replace(/attr\((.+?)\)/, (_, $1) => node.attrs[$1.trim()] || '')
                // 编码 \xxx
                .replace(/\\(\w{4})/, (_, $1) => String.fromCharCode(parseInt($1, 16)))
              return ''
            })
            var pseudo = {
              name: 'span',
              attrs: {
                style: item.style
              },
              children: [{
                type: 'text',
                text
              }]
            }
            if (item.pseudo == 'before')
              node.children.unshift(pseudo)
            else
              node.children.push(pseudo)
          } else
            matched[res - 1] += item.style + (item.style[item.style.length - 1] == ';' ? '' : ';')
        }
      }
    }
    matched = matched.join('')
    if (matched.length > 2)
      node.attrs.style = matched + (node.attrs.style || '')
  }
}

/**
 * @description 匹配样式
 * @param {object} node 要匹配的标签
 * @param {string|string[]} keys 选择器
 * @returns {number} 0：不匹配；1：name 匹配；2：class 匹配；3：id 匹配
 */
function match(node, keys) {

  function matchItem(key) {
    // 匹配 id
    if (key[0] == '#') {
      if (node.attrs.id && node.attrs.id.trim() == key.substr(1))
        return 3
    }
    // 匹配 class
    else if (key[0] == '.') {
      key = key.substr(1)
      var selectors = (node.attrs.class || '').split(' ')
      for (var i = 0; i < selectors.length; i++)
        if (selectors[i].trim() == key)
          return 2
    }
    // 匹配 name
    else if (node.name == key)
      return 1
    return 0
  }

  // 多选择器交集
  if (keys instanceof Array) {
    var res = 0
    for (var j = 0; j < keys.length; j++) {
      var tmp = matchItem(keys[j])
      // 任意一个不匹配就失败
      if (!tmp)
        return 0
      // 优先级最大的一个作为最终优先级
      if (tmp > res)
        res = tmp
    }
    return res
  }

  return matchItem(keys)
}
// #endif

module.exports = style
